package com.podigua.plugins.utils;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
import org.codehaus.plexus.languages.java.jpms.LocationManager;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsRequest;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsResult;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * maven 工具类
 *
 * @author podigua
 * @date 2023/11/27
 */
public class MavenUtils {
    /**
     * 获取classpath 路径
     *
     * @param project 项目
     * @return {@link List}<{@link File}>
     */
    public static List<File> getCompileClasspathElements(MavenProject project) {
        List<File> list = new ArrayList<>();
        list.add(new File(project.getBuild().getOutputDirectory()));
        list.addAll(project.getDependencies().stream().filter(d -> d.getSystemPath() != null && !d.getSystemPath().isEmpty()).map(d -> new File(d.getSystemPath())).collect(Collectors.toList()));
        list.addAll(project.getArtifacts().stream().sorted((a1, a2) -> {
            int compare = a1.compareTo(a2);
            if (compare == 0) {
                return a1.hasClassifier() ? 1 : (a2.hasClassifier() ? -1 : 0);
            }
            return compare;
        }).map(Artifact::getFile).collect(Collectors.toList()));
        return list.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 获取模块描述符
     *
     * @param project 项目
     * @return {@link File}
     * @throws MojoExecutionException mojo执行异常
     */
    public static File getModuleDescriptor(MavenProject project) throws MojoExecutionException {
        String outputDirectory = project.getBuild().getOutputDirectory();
        if (outputDirectory == null || outputDirectory.isEmpty()) {
            throw new MojoExecutionException("Error: Output directory doesn't exist");
        }

        File[] classes = new File(outputDirectory).listFiles();
        if (classes == null || classes.length == 0) {
            throw new MojoExecutionException("Error: Output directory is empty");
        }
        return Stream.of(classes).filter(file -> "module-info.class".equals(file.getName())).findFirst().orElse(null);
    }


    public static ResolvePathsResult<File> resolve(LocationManager locationManager, MavenProject project, File jdkHome) throws MojoExecutionException {
        File moduleDescriptor = getModuleDescriptor(project);
        List<File> artifacts = getCompileClasspathElements(project);
        ResolvePathsRequest<File> request = ResolvePathsRequest.ofFiles(artifacts);
        if (moduleDescriptor != null) {
            request.setMainModuleDescriptor(moduleDescriptor);
        }
        if (jdkHome != null && jdkHome.exists()) {
            request.setJdkHome(jdkHome);
        }
        try {
            return locationManager.resolvePaths(request);
        } catch (IOException e) {
            throw new MojoExecutionException("resolve", e);
        }
    }
}
